#include "protocolymodem.h"

#include <QFileInfo>
#include <QDir>

ProtocolYModem::ProtocolYModem(QSerialPort *serial):
    m_serial(serial),
    file(new QFile)
{

}

ProtocolYModem::~ProtocolYModem()
{
    delete file;
}

void ProtocolYModem::begin(Direction dir, QString &_path)
{
    if (dir == Transmit) {
        setSendPath(_path);
    } else {
        setReadPath(_path);
    }
}

void ProtocolYModem::run(Direction dir)
{
    if (dir == Transmit) {
        transmit();
    } else {
        receive();
    }
}

bool ProtocolYModem::over()
{
    YModem::Status status = getStatus();

    if(status != YModem::StatusFinish){
        return false;
    }

    return true;
}

void ProtocolYModem::setSendPath(const QString &_path)
{
    file->setFileName(_path);

    QFileInfo info(*file);

    FileProperty_t property;
    strncpy(property.name, info.fileName().toUtf8().data(), 64);
    property.size = info.size();

    fileSetProperty(&property);
}

void ProtocolYModem::setReadPath(const QString &_path)
{
    path = _path;
}

uint32_t ProtocolYModem::write(uint8_t *data, uint32_t len)
{
    uint32_t writeLen = m_serial->write((char *)data, len);
//    m_serial->waitForReadyRead(1000);

    return writeLen;
}

uint32_t ProtocolYModem::read(uint8_t *data, uint32_t len)
{
    if (!m_serial->bytesAvailable()) {
        return 0;
    }

    uint32_t readLen = m_serial->read((char *)data, len);
    return readLen;
}

int ProtocolYModem::fileOpen(FileOperateType type)
{
    switch(type) {
    case FileOpenReadOnly:
        if (!file->open(QIODevice::ReadOnly)) {
            return OperateFail;
        }
        break;

    case FileOpenWriteOnly:
        file->setFileName(path + "/" + QString(fileGetProperty()->name));
        if (!file->open(QIODevice::WriteOnly)) {
            return OperateFail;
        }
        break;

    case FileOpenReadWrite:
        if(!file->open(QIODevice::ReadWrite)){
            return OperateFail;
        }

    default:
        return OperateFail;
    }

    return OperateSuccess;
}

int ProtocolYModem::fileClose()
{
    if (file->isOpen()) {
        file->close();
    }

    return OperateSuccess;
}

uint32_t ProtocolYModem::fileWrite(uint8_t *data, uint32_t size)
{
    return file->write((char *)data, size);
}

uint32_t ProtocolYModem::fileRead(uint8_t *data, uint32_t size)
{
    return file->read((char *)data, size);
}

